package interfaces

import (
	"context"
	"net/http"
	"strconv"
	"zxstudy.com/application"
	"zxstudy.com/domain/entity"

	"github.com/gin-gonic/gin"
)

type Users struct {
	ua	application.UserApplication
}

func NewUserApplication(ua application.UserApplication) *Users {
	return &Users{
		ua: ua,
	}
}

/**
 * route: /user/
 * method: post
 */
func (u *Users) Create(c *gin.Context) {
	var user *entity.User

	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	newUser, err := u.ua.Register(context.Background(), user)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"user": newUser,
	})
}

/**
 * route: /user/:id
 * method: put
 */
func (u *Users) Update(c *gin.Context) {
	ctx := context.Background()
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	user, err := u.ua.Get(ctx, id)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	newUser, err := u.ua.Update(ctx, user)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"user": newUser,
	})
}

/**
 * route: /user/:id
 * method: get
 */
func (u *Users) Get(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	user, err := u.ua.Get(context.Background(), id)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"user": user,
	})
}

/**
 * route: /user
 * method: get
 */
func (u *Users) Users(c *gin.Context) {
	users, err := u.ua.Users(context.Background())
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"message": err.Error(),
		})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"users": users,
	})
}